<template>
  <div
    id="contextMenu"
    v-show="isContextMenuVisible"
    :style="{ top: contextMenuStyle.top, left: contextMenuStyle.left }"
    class="context-menu"
  >
    <div
      v-for="(option, index) in options"
      :key="index"
      @click="handleOptionClick(option.action)"
      class="context-menu-option"
    >
      <span class="icon">{{ option.icon }}</span>
      <!-- 增加图标 -->
      <span>{{ option.name }}</span>
      <span class="shortcut">{{ option.shortcut }}</span>
      <!-- 增加快捷键提示 -->
    </div>
  </div>
</template>

<script>
/**
 * 右键菜单组件
 * options : 菜单配置信息
 *
 * option: { name: 菜单项名称, action: 引用组件内需要调用的事件, icon: 菜单图标  shortcut: 快捷键提示, shortcutKey: 快捷键按钮组合，特殊符号需要使用英文名称 },
 *         { name: '上一页', action: this.prevPage, shortcut: "Alt+向上箭头", shortcutKey: 'alt + arrowup' },
 *
 * 引用组件 定义方法：  this.$refs.contextMenu.showContextMenu(event, this.contextMenuOption);
 *
 */

export default {
  name: "ContextMenu",
  props: {
    options: {
      type: Array,
      required: true,
      default: [],
    },
  },
  data() {
    return {
      isContextMenuVisible: false,
      contextMenuStyle: {
        top: "0px",
        left: "0px",
      },
      pressedKeys: [],
      timeout: null,
    };
  },
  mounted() {
    window.addEventListener("keydown", this.handleKeyDown);
    window.addEventListener("keyup", this.handleKeyUp);
    window.addEventListener("click", this.handleClickOutside);
  },
  beforeUnmount() {
    window.removeEventListener("keydown", this.handleKeyDown);
    window.removeEventListener("keyup", this.handleKeyUp);
    window.removeEventListener("click", this.handleClickOutside);
  },
  methods: {
    showContextMenu(event, options) {
      event.preventDefault(); // 阻止默认右键菜单
      this.isContextMenuVisible = true;

      const menuWidth = 280; // 计算弹窗的宽度，可以根据实际情况获取
      const windowWidth = window.innerWidth;
      const maxLeft = windowWidth - menuWidth; // 弹窗最大允许的 left 值

      let left = event.clientX;
      if (left > maxLeft) {
        left = maxLeft;
      }

      this.contextMenuStyle = {
        top: `${event.clientY}px`,
        left: `${left}px`,
      };
      // this.options = options;
    },
    hideContextMenu() {
      this.isContextMenuVisible = false;
    },
    handleOptionClick(action) {
      this.hideContextMenu();
      action(); // 执行传入的方法
    },

    /**
     * 按键按下事件
     * @param {*} event
     *
     * 1s内将按下的组合键装入数组，避免冲突
     *
     */
    handleKeyDown(event) {
      this.pressedKeys.push(event.key.toLowerCase());
      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        this.pressedKeys = [];
      }, 1200);
    },

    /**
     * 按键松开事件
     * @param {*} event
     *
     */
    handleKeyUp(event) {
      this.matchShortcut(event);
    },

    /**
     * 用于快捷键匹配菜单项并执行相应的方法
     * @param {*} event
     */
    matchShortcut(event) {
      for (const option of this.options) {
        if (option.shortcut && this.isShortcutPressed(option.shortcutKey)) {
          event.preventDefault(); // 阻止默认快捷键操作
          option.action(); // 执行对应选项的方法
          return;
        }
      }
    },

    /**
     * 按下按键 匹配菜单项快捷键
     * @param {*} shortcutKey
     */
    isShortcutPressed(shortcutKey) {
      const keys = shortcutKey
        .toLowerCase()
        .split("+")
        .map((key) => key.trim());
      if (keys.length !== this.pressedKeys.length) {
        return false;
      }
      for (const key of keys) {
        if (!this.pressedKeys.includes(key)) {
          return false;
        }
      }
      return true;
    },

    handleClickOutside(event) {
      if (!this.$el.contains(event.target)) {
        this.hideContextMenu();
      }
    },
  },
};
</script>

<style>
.context-menu {
  position: fixed;
  z-index: 1000;
  min-width: 100px;
  max-width: 300px;
  background-color: white;
  border: none;
  border-radius: 3px;
  box-shadow: 0 0 5px #ccc;
}

/* .context-menu-option {
    height: 30px;
    font-size: 14px;
    padding: 5px 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
} */

.context-menu-option {
  display: flex;
  font-size: 12px;
  align-items: center;
  justify-content: center;
  padding: 10px 5px;
  cursor: pointer;
}

.context-menu-option:not(:last-child) {
  border-bottom: 1px solid #eee;
}

.icon {
  margin-right: 20px;
  /* 控制图标与文字之间的间距 */
}

.shortcut {
  margin-right: 10px;
  margin-left: 40px;
  /* 将快捷键提示放置在右侧 */
  text-align: right;
  /* 文字靠右显示 */
}

.context-menu-option:hover {
  background-color: #f0f0f0;
}
</style>
